package com.fan.cachewebview.utils

import android.content.Context
import android.content.pm.PackageInfo
import android.content.pm.PackageManager
import android.text.TextUtils
import android.webkit.MimeTypeMap
import androidx.collection.ArraySet
import okhttp3.Headers
import java.io.ByteArrayOutputStream
import java.io.IOException
import java.io.InputStream
import java.security.MessageDigest
import java.util.*

/**
 * @description Okhttp工厂类
 * @date: 2022/2/23 11:30
 * @author: fan
 */
object AppUtils {

    // 获取应用版本号
    @Suppress("DEPRECATION")
    fun getVersionCode(context: Context): Int {
        val packageManager = context.packageManager
        val packageInfo: PackageInfo
        var versionCode = 0
        try {
            packageInfo = packageManager.getPackageInfo(context.packageName, 0)
            versionCode = packageInfo.versionCode
        } catch (e: PackageManager.NameNotFoundException) {
            e.printStackTrace()
        }
        return versionCode
    }

    fun generateHeadersMap(headers: Headers): Map<String, String>? {
        val headersMap: MutableMap<String, String> = HashMap()
        for (key in headers.names()) {
            val values = StringBuilder()
            for (value in listToSet(headers.values(key))) {
                if (!TextUtils.isEmpty(values)) {
                    values.append(" ")
                }
                values.append(value)
            }
            headersMap[key] = values.toString().trim { it <= ' ' }
        }
        return headersMap
    }

    private fun listToSet(origin: List<String?>): Set<String?> {
        val target: MutableSet<String?> = ArraySet(origin.size)
        target.addAll(origin)
        return target
    }


    /**
     * MD5 工具
     */
    fun getMD5(message: String): String {
        return getMD5(message, true)
    }

    private fun getMD5(message: String, upperCase: Boolean): String {
        var md5str = ""
        try {
            val md = MessageDigest.getInstance("MD5")
            val input = message.toByteArray()
            val buff = md.digest(input)
            md5str = bytesToHex(buff, upperCase)
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return md5str
    }

    private fun bytesToHex(bytes: ByteArray, upperCase: Boolean): String {
        val md5str = StringBuffer()
        var digital: Int
        for (i in bytes.indices) {
            digital = bytes[i].toInt()
            if (digital < 0) {
                digital += 256
            }
            if (digital < 16) {
                md5str.append("0")
            }
            md5str.append(Integer.toHexString(digital))
        }
        return if (upperCase) {
            md5str.toString().uppercase(Locale.getDefault())
        } else md5str.toString().uppercase(Locale.getDefault())
    }


    /**
     * 根据statusCode 获取状态值
     */
    fun getPhrase(statusCode: Int): String? {
        return when (statusCode) {
            100 -> "Continue"
            101 -> "Switching Protocols"
            200 -> "OK"
            201 -> "Created"
            202 -> "Accepted"
            203 -> "Non-Authoritative Information"
            204 -> "No Content"
            205 -> "Reset Content"
            206 -> "Partial Content"
            300 -> "Multiple Choices"
            301 -> "Moved Permanently"
            302 -> "Found"
            303 -> "See Other"
            304 -> "Not Modified"
            305 -> "Use Proxy"
            306 -> "Unused"
            307 -> "Temporary Redirect"
            400 -> "Bad Request"
            401 -> "Unauthorized"
            402 -> "Payment Required"
            403 -> "Forbidden"
            404 -> "Not Found"
            405 -> "Method Not Allowed"
            406 -> "Not Acceptable"
            407 -> "Proxy Authentication Required"
            408 -> "Request Time-out"
            409 -> "Conflict"
            410 -> "Gone"
            411 -> "Length Required"
            412 -> "Precondition Failed"
            413 -> "Request Entity Too Large"
            414 -> "Request-URI Too Large"
            415 -> "Unsupported Media Type"
            416 -> "Requested range not satisfiable"
            417 -> "Expectation Failed"
            500 -> "Internal Server Error"
            501 -> "Not Implemented"
            502 -> "Bad Gateway"
            503 -> "Service Unavailable"
            504 -> "Gateway Time-out"
            505 -> "HTTP Version not supported"
            else -> "unknown"
        }
    }


    /**
     * 获取资源文件的类型扩展名
     */
    fun getFileExtensionFromUrl(url: String): String? {
        var url = url
        url = url.lowercase(Locale.getDefault())
        if (!TextUtils.isEmpty(url)) {
            val fragment = url.lastIndexOf('#')
            if (fragment > 0) {
                url = url.substring(0, fragment)
            }
            val query = url.lastIndexOf('?')
            if (query > 0) {
                url = url.substring(0, query)
            }
            val filenamePos = url.lastIndexOf('/')
            val filename = if (0 <= filenamePos) url.substring(filenamePos + 1) else url

            // 如果文件名包含特殊字符，我们认为它对我们的匹配目的无效
            if (filename.isNotEmpty()) {
                val dotPos = filename.lastIndexOf('.')
                if (0 <= dotPos) {
                    return filename.substring(dotPos + 1)
                }
            }
        }
        return ""
    }

    fun getMimeTypeFromExtension(extension: String?): String? {
        return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
    }


    @Throws(IOException::class)
    fun streamToBytes(`in`: InputStream): ByteArray? {
        val out = ByteArrayOutputStream()
        val buffer = ByteArray(1024)
        var len: Int
        while (`in`.read(buffer).also { len = it } > -1) {
            out.write(buffer, 0, len)
        }
        out.flush()
        `in`.close()
        return out.toByteArray()
    }

}